package ferp.android.dialogs;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.*;
import android.widget.*;
import ferp.android.GUI;
import ferp.android.R;
import ferp.android.activities.Main;
import ferp.android.layouts.SquareLayout;
import ferp.android.views.PoolView;
import ferp.android.views.table.element.tutorial.ScrollableTextView;
import ferp.android.widgets.BidView;
import ferp.core.game.Bid;
import ferp.core.game.Game;
import ferp.core.game.Input;
import ferp.core.game.Settings;
import ferp.core.player.Profile;
import ferp.core.tutorial.Scenario;

/**
* User: igorgok
* Date: 5/29/12 2:21 PM
*/
public class PoolDialog extends Dialog
{
  public interface Listener
  {
    void onPoolDialogDismiss(Input.PoolUserChoice puc);
    void onSendReportRequested();
    void onShareClick();
  }

  public static void show(Main main, int id, boolean manual)
  {
    Bundle bundle = new Bundle();

    bundle.putBoolean(PoolDialog.MANUAL, manual);

    main.showDialog(id, bundle);
  }

  public static PoolDialog create(Context context, final Listener listener, Profile profile)
  {
    return profile == null || profile.game() == null ? null : new PoolDialog(context, listener);
  }

  @Override
  public void onBackPressed()
  {
    if (note.getVisibility() == View.VISIBLE)
      hideNote();
    else
      super.onBackPressed();
  }

  public void set(Profile profile, Bundle bundle)
  {
    boolean manual = bundle.getBoolean(PoolDialog.MANUAL);

    game = profile.game();

    pool.initialize(profile);
    pool.showWatermark(game.replay);

    boolean landscape = profile.isLandscape();
    DisplayMetrics metrics = new DisplayMetrics();
    LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(layoutButtons.getLayoutParams());
    LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(bid.getLayoutParams());

    ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(metrics);
    // button layout height
    lp1.height = Math.round(Math.min(metrics.widthPixels, metrics.heightPixels) * (landscape ? 0.1f : 0.13f));
    layoutButtons.setLayoutParams(lp1);
    // bid view height
    lp2.height = Math.round(lp1.height / 2.0f);
    bid.setLayoutParams(lp2);

    // show/hide buttons
    layoutButtons.setVisibility(manual ? View.GONE : View.VISIBLE);

    if (!manual)
    {
      // show/hide "replay" button - can't use 'isShown' method as a dialog itself is not shown yet
      replay.setVisibility(game.tutorial() || profile.games().initial == null ? View.GONE : View.VISIBLE);
      scoring.setVisibility(game.tutorial() ? View.VISIBLE : View.GONE);

      if (game.tutorial())
      {
        Scenario scenario = game.scenario();
        Settings.Locale locale = profile.settings.locale;

        note.setText(scenario.getScoringText(locale));
      }

      bid.show(game.declarer() == null ? Bid.pass() : game.getDeclarerBid().current, true);

      for (int id = 0; id < Game.PLAYERS; ++id)
      {
        String text = String.valueOf(game.getTricks(id));
        //int color = Color.BLACK;

        switch (game.getBid(id).current.type)
        {
          case WITHOUT_3:
            // a terrible hack!
            Bid b = new Bid(game.getBid(id).current);

            b.type = Bid.Type.PLAY;
            text = String.valueOf(b.tricks - 3);
            bid.show(b, false);
/*
          case PLAY:
            color = g.getTricks(id) < g.getBid(id).current.tricks ? Color.RED : Color.GREEN;
            break;
          case MISERE:
            color = g.getTricks(id) == 0 ? Color.GREEN : Color.RED;
            break;
          case WHIST:
            color = GUI.Color.NORMAL;
            break;
          case PASS:
            color = Color.DKGRAY;
*/
            break;
        }

        //tricks[id].setBackgroundResource(bgr);
        tricks[id].setText(text);
        tricks[id].setTextColor(GUI.Color.NORMAL);
      }
    }

    // show/hide buttons tricks
    layoutTricks.setVisibility(manual ? View.GONE : View.VISIBLE);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {
    getOwnerActivity().getMenuInflater().inflate(R.menu.pool, menu);
    menu.findItem(R.id.pool_report_game).setIcon(android.R.drawable.ic_menu_send);

    return true;
  }

  @Override
  public boolean onMenuItemSelected(int featureId, MenuItem item)
  {
    switch (item.getItemId())
    {
      case R.id.pool_report_game:
        listener.onSendReportRequested();
        return true;

      default:
        return super.onMenuItemSelected(featureId, item);
    }
  }

  /**
   *
   * @param context
   * @param listener
   * Make specific button non-clickable once it clicked.
   * No need to reset button's clickable state as the dialog is removed in onPoolDialogDismiss event.
   */
  private PoolDialog(final Context context, final Listener listener)
  {
    super(context, R.layout.dialog_pool);

    this.listener = listener;

    resolveWidgets();
    setupListeners();

    //Log.debug(Log.TAG, "PD: display is " + metrics.widthPixels + "x" + metrics.heightPixels + ", buttons height " + lp.height);

    //layout.measure(View.MeasureSpec.makeMeasureSpec(metrics.widthPixels, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(metrics.heightPixels, View.MeasureSpec.EXACTLY));

    //Log.debug(Log.TAG, "PD: " + pool.getMeasuredWidth() + "x" + pool.getMeasuredHeight());
  }

  private void resolveWidgets()
  {
    pool = (PoolView)findViewById(R.id.dlg_pool_view);

    layoutTricks = (TableLayout)findViewById(R.id.dlg_pool_layout_tricks);
    tricks[0] = resolve(R.id.dlg_pool_tricks_human);
    tricks[1] = resolve(R.id.dlg_pool_tricks_left);
    tricks[2] = resolve(R.id.dlg_pool_tricks_right);
    bid = (BidView)findViewById(R.id.dlg_pool_bid);

    layoutButtons = (LinearLayout)findViewById(R.id.dlg_pool_layout_buttons);
    initialPosition = new ActionButton(R.id.dlg_pool_initial_position, R.id.dlg_pool_button_simple, R.drawable.pool_initial_position);
    replay = new ActionButton(R.id.dlg_pool_replay, R.id.dlg_pool_button_simple, R.drawable.pool_replay);
    scoring = new ActionButton(R.id.dlg_pool_scoring, R.id.dlg_pool_button_toggle, R.drawable.pool_scoring);
    share = new ActionButton(R.id.dlg_pool_share, R.id.dlg_pool_button_simple, R.drawable.pool_share);

    note = (ScrollableTextView)findViewById(R.id.dlg_pool_scoring_note);
  }

  private void setupListeners()
  {
    registerForContextMenu(pool);
    pool.setOnCreateContextMenuListener(this);

    pool.setOnClickListener(new View.OnClickListener()
    {
      public void onClick(View view)
      {
        if (pool.isClickable())
        {
          pool.setClickable(false);
          puc = Input.PoolUserChoice.CONTINUE;

          dismiss();
        }
      }
    });

    setOnCancelListener(new OnCancelListener()
    {
      @Override
      public void onCancel(DialogInterface dialogInterface)
      {
        // use pool view's 'icClickable' method as indicator to prevent processing multiply events
        if (pool.isClickable())
        {
          pool.setClickable(false);
          puc = Input.PoolUserChoice.CONTINUE;
        }
      }
    });

    setOnDismissListener(new OnDismissListener()
    {
      public void onDismiss(DialogInterface dialogInterface)
      {
        listener.onPoolDialogDismiss(puc);
      }
    });

    initialPosition.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        if (pool.isClickable())
        {
          pool.setClickable(false);
          puc = Input.PoolUserChoice.SHOW_INITIAL_POSITION;

          dismiss();
        }
      }
    });

    replay.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        if (pool.isClickable())
        {
          pool.setClickable(false);
          puc = Input.PoolUserChoice.REPLAY;

          dismiss();
        }
      }
    });

    scoring.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        if (scoring.isChecked())
          showNote();
        else
          hideNote();
      }
    });

    share.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        listener.onShareClick();
      }
    });

    note.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        hideNote();
      }
    });

    setOnShowListener(new OnShowListener()
    {
      @Override
      public void onShow(DialogInterface dialogInterface)
      {
        if (game.tutorial())
          showNote();
      }
    });
  }

  private void showNote()
  {
    int w = Math.round(pool.getWidth() * 0.8f);
    int h = Math.round(pool.getHeight() * 0.3f);

    note.measure(View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.AT_MOST));
    note.setLayoutParams(new FrameLayout.LayoutParams(note.getMeasuredWidth(), note.getMeasuredHeight(), Gravity.CENTER));
    note.setVisibility(View.VISIBLE);

    scoring.setChecked(true);
  }

  private void hideNote()
  {
    note.setVisibility(View.GONE);
    note.scrollTo(note.getScrollX(), 0);

    scoring.setChecked(false);
  }

  private TextView resolve(int id)
  {
    TextView tv = (TextView)findViewById(id);

    tv.setTypeface(GUI.Font.BOLD);

    return tv;
  }

  // designates whether pool dialog opened manually from context menu or automatically
  private static final String MANUAL = "manual";

  private final class ActionButton
  {
    private SquareLayout layout;
    private Button button;

    private ActionButton(int resLayout, int resButton, int resImage)
    {
      this.layout = (SquareLayout)PoolDialog.this.findViewById(resLayout);
      this.button = (Button)layout.findViewById(resButton);

      ImageView iv = (ImageView)layout.findViewById(R.id.dlg_pool_button_image);

      iv.setBackgroundResource(resImage);
    }

    private void setOnClickListener(View.OnClickListener ocl) {button.setOnClickListener(ocl);}
    private void setVisibility(int visibility) {layout.setVisibility(visibility);}
    private void setChecked(boolean checked) {((ToggleButton)button).setChecked(checked);}
    private boolean isChecked() {return ((ToggleButton)button).isChecked();}
  }

  // the game object
  private Game game;

  // widgets
  private PoolView pool;
  private TableLayout layoutTricks;
  private TextView[] tricks = new TextView[Game.PLAYERS];
  private BidView bid;

  private LinearLayout layoutButtons;
  private ActionButton initialPosition;
  private ActionButton replay;
  private ActionButton scoring;
  private ActionButton share;

  private ScrollableTextView note;

  // dialog event listener
  private final Listener listener;

  // user choice
  private Input.PoolUserChoice puc = Input.PoolUserChoice.CONTINUE;
}
